from datetime import datetime
from typing import Optional, List, ClassVar

from sqlmodel import Field, Relationship, SQLModel

from app.core.database import ActiveRecord
from app.core.models import TimestampMixin


# 基本对象一般用于输入
class User(SQLModel, TimestampMixin):
    id: Optional[int] = Field(default=None, primary_key=True)
    STATUS_ACTIVE: ClassVar[int] = 0
    STATUS_INACTIVE: ClassVar[int] = -1
    status: int = Field(default=STATUS_ACTIVE, description="状态：0=正常，-1=停用")
    nickname: str = Field(description="昵称")
    avatar: Optional[str] = Field(default=None, description="头像")
    name: Optional[str] = Field(default=None, description="姓名")
    email: Optional[str] = Field(default=None, description="邮箱")
    phone: Optional[str] = Field(default=None, description="电话")


# 全对象一般用于输出
class UserWhole(User):
    login_accounts: List["LoginAccount"] | None = None
    weixin_accounts: List["WeixinAccount"] | None = None
    roles: List["Role"] | None = None


class UserRoleEntity(SQLModel, table=True):
    __tablename__ = "a_user_role"
    user_id: int = Field(foreign_key="a_user.id", primary_key=True, description="用户Id")
    role_id: int = Field(foreign_key="a_role.id", primary_key=True, description="角色Id")


# 实体对象用于orm，理论上和全对象兼容但不能混用
class UserEntity(User, ActiveRecord, table=True):
    __tablename__ = "a_user"
    login_accounts: List["LoginAccountEntity"] = Relationship(back_populates="user")
    weixin_accounts: List["WeixinAccountEntity"] = Relationship(back_populates="user")
    roles: List["RoleEntity"] = Relationship(back_populates="users", link_model=UserRoleEntity)


class LastAccessMixin:
    last_accessed_at: Optional[datetime] = Field(default=None, description="最后访问时间")
    last_accessed_via: Optional[str] = Field(default=None, description="最后访问IP")


class LoginAccount(SQLModel, LastAccessMixin):
    id: Optional[int] = Field(default=None, primary_key=True)
    username: str = Field(unique=True, description="用户名")
    hashed_password: Optional[str] = Field(default=None, description="密码")
    user_id: int = Field(foreign_key="a_user.id", description="用户Id")


class LoginAccountEntity(LoginAccount, ActiveRecord, table=True):
    __tablename__ = "a_login_account"
    user: "UserEntity" = Relationship(back_populates="login_accounts")


class WeixinAccount(SQLModel, LastAccessMixin):
    id: Optional[int] = Field(default=None, primary_key=True)
    open_id: str = Field(description="微信OpenId")
    union_id: Optional[str] = Field(default=None, description="微信UnionId")
    user_id: int = Field(foreign_key="a_user.id", description="用户Id")


class WeixinAccountEntity(WeixinAccount, ActiveRecord, table=True):
    __tablename__ = "a_weixin_account"
    user: "UserEntity" = Relationship(back_populates="weixin_accounts")


class RolePermissionEntity(SQLModel, table=True):
    __tablename__ = "a_role_permission"
    role_id: int = Field(foreign_key="a_role.id", primary_key=True, description="角色Id")
    permission_id: int = Field(foreign_key="a_permission.id", primary_key=True, description="权限Id")


class Role(SQLModel):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str = Field(unique=True, description="名称")


class RoleWhole(Role):
    permissions: List["Permission"] | None = None


class RoleEntity(Role, ActiveRecord, table=True):
    __tablename__ = "a_role"
    permissions: List["PermissionEntity"] = Relationship(back_populates="roles", link_model=RolePermissionEntity)
    users: List["UserEntity"] = Relationship(back_populates="roles", link_model=UserRoleEntity)


class Permission(SQLModel):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str = Field(unique=True, description="名称")


class PermissionEntity(Permission, ActiveRecord, table=True):
    __tablename__ = "a_permission"
    roles: List["RoleEntity"] = Relationship(back_populates="permissions", link_model=RolePermissionEntity)
